<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title></title>
	<link rel="stylesheet" href="">
</head>
<body>
<script src='http://cdn.jsdelivr.net/vue/1.0.26/vue.js'></script>
<!-- <script src="https://cdn.bootcss.com/vue/2.5.8/vue.js"></script> -->
<div id="root">
	<div id="todo">
		<todo-form username='Lily'></todo-form>
		<todo-list ></todo-list>
	</div>
</div>
<script>
	/**
	 * 上面讲到的 props 其实就是父组件向子组件传递消息的一种方式。 
	 * 在子组件中有一个 this.$parent 和 this.$root 可以用来方法父组件和根实例。不过，现在我们
	 * 应该避免这么做。因为组件本身就是为了封装独立的逻辑，如果又去直接访问父组件的数据就破坏
	 * 了组件的封装性。 
	 * 所以我们应该还是应该通过父组件向子组件传递 props 的方式来通信。
	 * 当然 props 其实只能做回调。在 React 中就探讨过这个问题，React 的做法就是通过 props 来
	 * 做，传一个回调函数给子组件。其实我不是很喜欢这种把回调函数传来传去的方式，我更喜欢的是
	 * 事件的方式。Vue 中子组件可以通过通过事件和父组件进行通信的。向父组件发消息是通过 
	 * this.$dispatch，而向子组件发送消息是通过 this.$boardcast，这里都是向所有的父亲和孩子发
	 * 送消息，但是一旦执行一个回调之后就会停止，除非这个回调函数显式返回了 true
	 * 我们把之前的Todo List拆成不同的组件来实现，这样可以体验下如何进行组件的双向通信，
	 * 我们拆分出两个组件，分别是 List 和 Form 。
	 */
	//Form 负责处理用户输入，并在提交表单的时候向父组件发送一个 add 消息
	var Form = Vue.extend({//局部注册一个组件
	 props: {//prop验证
		 username: {
		 	type: String,
		 	default: "Unnamed"
		 }
	 },
	 data: function() {//初始化input
		 return {
		 	input: "",
		 };
	 },
	 template: `
	    <div>
		 <h1>{{username}}'s Todo List</h1>
		 <form v-on:submit="add" v-on:submit.prevent>
		 	<input type="text" v-model="input"/>
		 	<input type="submit" value='add' />
		 </form>
		</div>
	 `,
	 methods: {
		 add: function() {//自定义方法
		 	console.log(this.$dispatch)
		 	this.$dispatch("add", this.input); //这里就是向父组件发送消息 冒泡
		 	this.input = "";
		 }
	 }
});
// List 只负责展示列表和处理用户勾选操作，它接收到 add 消息之后会在自己上添加一个条目
var List = Vue.extend({
	 template: `
	 	<div>
		 <ul>
		 <li v-for='todo in list'>
		 <label v-bind:class="{ done : todo.done }" >
		  <input type="checkbox" v-model="todo.done"/>
		  {{todo.title}}
		 </label>
		 </li>
		 </ul>
		</div>`,
	 props: {
		 initList: {
		 	type: Array
		 }
	 },
	 data: function() {
		 return {
		 	list: []
		 }
	 },
	 events: {
		 add: function(input) {
		 	console.log(input)
		 	if(!input) return false;
		 	this.list.unshift({
		 		title: input,
		 		done: false
		 	});
		 }
	 }
});
// 注意，其实 Form 和 List 在逻辑上是平级的组件，所以他们没有父子关系，他们共同都是 vm 的孩子。这里 vm 接到 Form 的消息之后会转发给 List。
var vm = new Vue({
 el: "#root",
 components: {
 	"todo-form": Form,
 	"todo-list": List
 },
  events: {
 	add: function(input) {
 		this.$broadcast("add", input);//其实就是让List去执行add事件 参数为input
 	}
 }
})
</script>	
</body>
</html>